﻿using System;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Framework.Serialization;
using IQIGame.Onigao.GamePlay;
using LFloatMath.Math;

namespace IQIGame.Onigao.Logic
{
    public class SkillEffective_Damage : SkillEffective
    {
        protected override ISerializeCustomPOD OnExecute(SkillEffectiveData data, Unit target, SkillEffectiveContext context, int effectiveIndex, out SkillEffectiveResponse startResp)
        {
            startResp = null;
            var rAttacker = context.skill.executer;
            if (data.effectiveConfig.customConfig is SkillEffective_Damage_ConfigData rConfig)
            {
                target.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_SkillDamageTempModify, context);

                // 作为技能效果时，集成了扣除弱点值
                var rSkill = context.skill;
                var rDamageType = (EDamageType)(1 << rSkill.config.DamageType);
                DamageController.TakeWeaknessHit(rAttacker, target, rDamageType, rSkill.config.WeaknessHit);

                var rDamageResp = DamageController.TakeDamageBySkill(rAttacker, target, context.skill, context.correct,
                    rConfig.hitFormula, rConfig.critFormula, rConfig.damageFormula, rConfig.checkDead);
                var rCustom = target.GetComponent<CustomPropertyComponent>(ETComponentType.CustomPropertyComponent);
                rCustom.SetProperty(ECustomProperty.LastHitSelf, rAttacker.GUID, ETAnyType.Int32);
                rAttacker.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_SkillDamage, rDamageResp, context.skill);
                return rDamageResp;
            }
            return null;
        }

        protected override ISerializeCustomPOD OnActionExecute(SkillEffectiveData data, SkillActionNode action, Unit target, ref SkillEffectiveContext context, int effectiveIndex)
        {
            var rAttacker = context.skill.executer;
            if (action.customConfig is SkillEffectiveAction_Damage_ConfigData rData)
            {
                target.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_SkillDamageTempModify, context);

                var bHit = rData.hit?.GetValue(rAttacker, target, context) ?? true;
                var bCrit = rData.crit?.GetValue(rAttacker, target, context) ?? false;
                var nDamage = rData.damage.GetValue(rAttacker, target, context);

                var rSkill = context.skill;
                var rSkillType = rSkill.config.SkillType;
                var rAtkType = rSkillType == 1 ? EDamageFrom.CommonAtk : EDamageFrom.Skill;
                var rBackstab = target.CheckBackstab(rAttacker.pos - target.pos);
                var rDamageResp = DamageController.TakeDamageWithoutFormula(rAttacker, target, rAtkType,
                    bHit, bCrit, nDamage, (EDamageType)(1 << rSkill.config.DamageType), rSkill.skillID, rData.checkDead, rBackstab);

                context.AddRuntimeData(target, action.guid, BattleConst.FinalDamage, rDamageResp.finalDamage.ToLFloat());
                context.AddRuntimeData(target, action.guid, BattleConst.Crit, rDamageResp.crit);

                var rCustom = target.GetComponent<CustomPropertyComponent>(ETComponentType.CustomPropertyComponent);
                rCustom.SetProperty(ECustomProperty.LastHitSelf, rAttacker.GUID, ETAnyType.Int32);
                rAttacker.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_SkillDamage, rDamageResp, context.skill);
                return rDamageResp;
            }
            return null;
        }

#if UNITY_EDITOR
        public override string ToString(SkillCustomConfig config)
        {
            var rConfig = config as SkillEffective_Damage_ConfigData;
            return $"造成伤害，命中:[{rConfig.hitFormula}],暴击:[{rConfig.critFormula}],伤害:[{rConfig.damageFormula}]";
        }
#endif
    }
}